home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / v10n06.arc / XBUF.C < prev    next >
Text File  |  1991-03-06  |  3KB  |  145 lines

  1. // xbuf.C - Extends BIOS keystroke buffer.
  2.  
  3. #include <alloc.H>
  4. #include <dos.H>
  5.  
  6. #include "xbuf.H"
  7.  
  8. // installation Flag 
  9. static int installed = 0;
  10.  
  11. // Queue Variables 
  12. static int *q;
  13. static int qsize;
  14. static int head, tail;
  15.  
  16. // Miscellaneous 
  17. #define    ZERO_FLAG    64
  18. union REGS r;
  19. static void interrupt (*Old_Timer_Int)(void);
  20.  
  21. // Function Prototypes 
  22. int c_break(void);
  23. int keypress(void);
  24. void interrupt New_Timer_Int(void);
  25.  
  26. /* A replacement for Control-break processing, this function is
  27.    installed via ctrlbrk(). It returns 1 to indicate that breaks
  28.    are to be ignored.  "^C" is still displayed.
  29. */
  30. static int c_break(void)
  31.     {
  32.     return 1;
  33.     }
  34.  
  35. /* Returns the next key from the queue. Returns 0 if xbuf has not
  36.    been installed.
  37. */
  38. int getkey(void)
  39.     {
  40.     int key;
  41.  
  42.     if(!installed)
  43.         return 0;
  44.  
  45.     while(!iskey())
  46.         ;
  47.     disable ();
  48.     key = q[head = (head + 1) % qsize];
  49.     enable ();
  50.     return key;
  51.     }
  52.  
  53. /* Returns non-zero if a keystroke is present in the xbuf buffer,
  54.    or returns 0 if none are present or xbuf has not been installed.
  55.  */
  56. int iskey(void)
  57.     {
  58.     int flag;
  59.  
  60.     if(!installed)
  61.         return 0;
  62.  
  63.     disable();
  64.     flag = head != tail;
  65.     enable();
  66.  
  67.     return flag;
  68.     }
  69.  
  70. /* Returns non-zero if one or more keystrokes are present in the BIOS
  71.    key buffer, or returns zero.
  72.  */
  73. static int keypress(void)
  74.     {
  75.     r.h.ah = 1;
  76.     int86(0x16, &r, &r);
  77.     return (r.x.flags & ZERO_FLAG) ? 0 : 1;
  78.     }
  79.  
  80. /* Replacement for the timer interrupt. With every 'tick' of the timer,
  81.    it calls the old timer interrupt, then, checks the BIOS key buffer
  82.    for keystrokes. Each keystroke is placed in the xbuf buffer.
  83.  */
  84. static void interrupt New_Timer_Int(void)
  85.     {
  86.     register keystroke, temp;
  87.  
  88.     (*Old_Timer_Int)();
  89.  
  90.     if(keypress())
  91.         {
  92.         _AH = 0;  /* Get keystroke */
  93.         geninterrupt(0x16);
  94.  
  95.         keystroke = _AX;
  96.         if(keystroke & 0x00ff)
  97.             keystroke &= 0x00ff;
  98.  
  99.         if((temp = (tail + 1) % qsize) == head)
  100.             return;  /* Exit if queue full */
  101.  
  102.         q[tail = temp] = keystroke;
  103.         }
  104.     }
  105.  
  106. /* Installs xbuf buffer.
  107.    To install: xbuf_install(bufsize);
  108.    buffer size must be 255 or less
  109.  
  110.    returns either ERROR or OK
  111. */
  112. int xbuf_install(int size)
  113.     {
  114.     if(installed)
  115.         return ERROR;
  116.  
  117.     if((qsize = size) < DEFAULT_SIZE || qsize > 255)
  118.         return ERROR;
  119.  
  120.     if((q = (int *)malloc(qsize * sizeof(int))) == NULL)
  121.         return ERROR;
  122.  
  123.     qsize++;  // Circular queues are one element larger
  124.     head = tail = 0;
  125.     ctrlbrk(c_break);
  126.     Old_Timer_Int = getvect(0x1c);
  127.     setvect(0x1c, New_Timer_Int);
  128.     installed = 1;
  129.     return OK;
  130.     }
  131.  
  132. /* removes xbuf buffer
  133.  
  134.    returns either ERROR or OK
  135. */
  136. int xbuf_remove(void)
  137.     {
  138.     if(!installed)
  139.         return ERROR;
  140.  
  141.     setvect(0x1c, Old_Timer_Int);
  142.     installed = 0;
  143.     return OK;
  144.     }
  145.